
package com.gitee.jmash.rbac.dao;

import com.crenjoy.proto.utils.TypeUtil;
import com.gitee.jmash.common.utils.UUIDUtil;
import com.gitee.jmash.core.orm.jpa.SqlBuilder;
import com.gitee.jmash.core.orm.jpa.TenantEntityManager;
import com.gitee.jmash.core.orm.jpa.TreeBaseDao;
import com.gitee.jmash.rbac.entity.ResourceEntity;
import com.gitee.jmash.rbac.model.TreeResult;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import jmash.rbac.protobuf.ResourceReq;

/**
 * Resource实体的Dao层（使用JPA实现）.
 *
 * @author <a href="mailto:service@crenjoy.com">crenjoy</a>
 */
public class ResourceDao extends TreeBaseDao<ResourceEntity, UUID> {

  public ResourceDao() {
    super();
  }

  public ResourceDao(TenantEntityManager tem) {
    super(tem);
  }

  /** 更新是否叶子节点. */
  public void updateLeaf() {
    String  sql=" update  ResourceEntity a set a.isLeaf = NOT EXISTS ( SELECT 1 FROM ResourceEntity b WHERE b.parentId = a.resourceId ) ";
    this.executeUpdate(sql);
  }

  /** 模块是否关联资源. */
  public boolean isRelationModule(UUID moduleId) {
    String sql = "select count(s.resourceId) from ResourceEntity s where s.moduleId = ?1 ";
    Object count = this.findSingleResult(sql, moduleId);
    return Integer.parseInt(count.toString()) > 0 ? true : false;
  }

  /** 通过资源路径查询资源实体. */
  public ResourceEntity findByUrl(String url) {
    return this.findSingle("select s from ResourceEntity s where s.url = ?1 ", url);
  }

  /**
   * 综合查询.
   */
  public List<ResourceEntity> findListByReq(ResourceReq req) {
    SqlBuilder sqlBuilder = createSql(req);
    String query = sqlBuilder.getQuerySql("select s ");
    return this.findListByParams(query, sqlBuilder.getParams());
  }

  /** 判断是否有子资源. */
  public boolean isHaveChild(UUID resourceId) {
    String sql = "select count(s.resourceId) from ResourceEntity s where s.parentId = ?1";
    Object count = this.findSingleResult(sql, resourceId);
    return Integer.parseInt(count.toString()) > 0 ? true : false;
  }

  public List<TreeResult> findTreeListByReq(ResourceReq req) {
    SqlBuilder sqlBuilder = createSql(req);
    String query = sqlBuilder.getQuerySql(
        "select s.resourceId as value,s.resourceName as label,s.parentId as parentId,s.orderBy as orderBy");
    return this.findDtoListByParams(query, TreeResult.class, sqlBuilder.getParams());
  }


  /** Create SQL By Req . */
  public SqlBuilder createSql(ResourceReq req) {
    StringBuilder sql = new StringBuilder(" from ResourceEntity s where 1=1  ");
    Map<String, Object> params = new HashMap<String, Object>();

    if (!TypeUtil.isEmpty(req.getModuleId())) {
      sql.append(" and s.moduleId = :moduleId ");
      params.put("moduleId", UUIDUtil.fromString(req.getModuleId()));
    }

    if (StringUtils.isNotBlank(req.getParentId())) {
      sql.append(" and s.parentId = :parentId ");
      params.put("parentId", UUIDUtil.fromString(req.getParentId()));
    }

    if (req.getHasHidden()) {
      sql.append(" and s.hidden = :hidden ");
      params.put("hidden", req.getHidden());
    }

    if (StringUtils.isNotBlank(req.getLikeResourceName())) {
      sql.append(" and s.resourceName like :likeResourceName ");
      params.put("likeResourceName", "%" + req.getLikeResourceName() + "%");
    }

    String orderSql = "order by s.depth , s.orderBy ";
    return SqlBuilder.build().setSql(sql).setParams(params).setOrderSql(orderSql);
  }
}
